package com.training.service;

import com.training.entity.OfflinePractice;
import com.training.entity.PracticeEnrollment;
import com.training.mapper.OfflinePracticeMapper;
import com.training.mapper.PracticeEnrollmentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class PracticeEnrollmentService {

    private final PracticeEnrollmentMapper enrollmentMapper;
    private final OfflinePracticeMapper practiceMapper;

    @Autowired
    public PracticeEnrollmentService(PracticeEnrollmentMapper enrollmentMapper, OfflinePracticeMapper practiceMapper) {
        this.enrollmentMapper = enrollmentMapper;
        this.practiceMapper = practiceMapper;
    }

    /**
     * Handles student enrollment with re-enrollment logic.
     * If a canceled enrollment exists, it updates it. Otherwise, it creates a new one.
     * @param enrollmentDetails The new enrollment information from the form.
     */
    @Transactional
    public void enroll(PracticeEnrollment enrollmentDetails) {
        // 1. Basic validation
        if (enrollmentDetails.getEnrollmentName() == null || enrollmentDetails.getEnrollmentPhone() == null ||
                enrollmentDetails.getEnrollmentName().trim().isEmpty() || enrollmentDetails.getEnrollmentPhone().trim().isEmpty()) {
            throw new IllegalArgumentException("姓名和电话均不能为空。");
        }
        OfflinePractice practice = practiceMapper.findById(enrollmentDetails.getPracticeId());
        if (practice == null || !"进行中".equals(practice.getStatus())) {
            throw new IllegalStateException("该实践当前不可报名。");
        }

        // 2. Check for ANY existing enrollment for this student and practice
        PracticeEnrollment existingEnrollment = enrollmentMapper.findByStudentAndPracticeIds(
                enrollmentDetails.getStudentId(),
                enrollmentDetails.getPracticeId()
        );

        if (existingEnrollment != null) {
            // 3. A record already exists, decide what to do
            if ("ENROLLED".equals(existingEnrollment.getStatus())) {
                // If already actively enrolled, prevent re-enrollment.
                throw new IllegalStateException("您已经报名了此实践，请勿重复报名。");
            } else {
                // If it was 'CANCELED', update the existing record to re-enroll.
                existingEnrollment.setEnrollmentName(enrollmentDetails.getEnrollmentName());
                existingEnrollment.setEnrollmentPhone(enrollmentDetails.getEnrollmentPhone());
                existingEnrollment.setNotes(enrollmentDetails.getNotes());
                existingEnrollment.setStatus("ENROLLED"); // Set status back to ENROLLED
                enrollmentMapper.updateEnrollment(existingEnrollment);
            }
        } else {
            // 4. No record exists, so insert a new one.
            enrollmentDetails.setStatus("ENROLLED");
            enrollmentMapper.insert(enrollmentDetails);
        }
    }

    /**
     * Cancels an existing enrollment.
     * @param enrollmentId The ID of the enrollment to cancel.
     * @param studentId The ID of the student making the request, for authorization.
     */
    @Transactional
    public void cancelEnrollment(Long enrollmentId, Long studentId) {
        PracticeEnrollment enrollment = enrollmentMapper.findById(enrollmentId);
        if (enrollment == null || !enrollment.getStudentId().equals(studentId)) {
            throw new SecurityException("您无法取消不属于您的报名记录。");
        }
        if (!"ENROLLED".equals(enrollment.getStatus())) {
            throw new IllegalStateException("该报名记录已是取消或其它状态，无法取消。");
        }
        enrollmentMapper.updateStatus(enrollmentId, studentId, "CANCELED");
    }

    /**
     * Retrieves all enrollments for a specific student.
     * @param studentId The ID of the student.
     * @return A list of the student's enrollments.
     */
    public List<PracticeEnrollment> getMyEnrollments(Long studentId) {
        return enrollmentMapper.findByStudentId(studentId);
    }
}